package negocio;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

@Entity
@Table(name="LVTP_CLIENTES")
public class Cliente
{
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column (name="ID_CLIENTE")
	private Integer codigo;
	@Column (name="N_CLIENTE", nullable=false, length=50)
	private String nombre;
	@Column (name="CUIT", nullable=false, length=30)
	private String cuit;
	@Column (name="DIRECCION", length=100)
	private String direccion;
	@Column (name="TELEFONO", length=30)
	private String telefono;
	
	@OneToOne
	@JoinColumn(name="ID_CONDICION_TRIBUTARIA")
	private CondicionTributaria condicionTributaria;
	
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
	@JoinColumn(name="ID_CLIENTE")
	private Set<CondicionDePagoCliente> condicionesDePago;
	
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	@LazyCollection(LazyCollectionOption.FALSE)
	@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
	@JoinColumn(name="ID_CLIENTE")
	private Set<OrdenDePedidoCliente> ordenesDePedidos;
	
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	@LazyCollection(LazyCollectionOption.FALSE)
	@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
	@JoinColumn(name="ID_CLIENTE")
	private Set<OrdenDeCotizacionCliente> ordenesDeCotizacion;
	
	@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	@LazyCollection(LazyCollectionOption.FALSE)
	@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
	@JoinColumn(name="ID_CLIENTE")
	private Set<DescuentoCliente> descuentos;
	
	public Cliente()
	{
		this.condicionesDePago = new HashSet<CondicionDePagoCliente>();	
		this.ordenesDePedidos = new HashSet<OrdenDePedidoCliente>();
		this.ordenesDeCotizacion = new HashSet<OrdenDeCotizacionCliente>();
		this.descuentos = new HashSet<DescuentoCliente>();
	}
	
	public Integer getCodigo() {
		return codigo;
	}
	public void setCodigo(Integer codigo) {
		this.codigo = codigo;
	}
	public String getNombre() {
		return nombre;
	}
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	public String getCuit() {
		return cuit;
	}
	public void setCuit(String cuit) {
		this.cuit = cuit;
	}
	public String getDireccion() {
		return direccion;
	}
	public void setDireccion(String direccion) {
		this.direccion = direccion;
	}
	public String getTelefono() {
		return telefono;
	}
	public void setTelefono(String telefono) {
		this.telefono = telefono;
	}
	
	public CondicionTributaria getCondicionTributaria() {
		return condicionTributaria;
	}

	public void setCondicionTributaria(CondicionTributaria condicionTributaria) {
		this.condicionTributaria = condicionTributaria;
	}

	public Set<CondicionDePagoCliente> getCondicionesDePago() {
		return condicionesDePago;
	}
	public void setCondicionesDePago(Set<CondicionDePagoCliente> condicionesDePago) {
		this.condicionesDePago = condicionesDePago;
	}

	public Set<OrdenDePedidoCliente> getOrdenesDePedidos() {
		return ordenesDePedidos;
	}

	public void setOrdenesDePedidos(Set<OrdenDePedidoCliente> ordenesDePedidos) {
		this.ordenesDePedidos = ordenesDePedidos;
	}

	public Set<OrdenDeCotizacionCliente> getOrdenesDeCotizacion() {
		return ordenesDeCotizacion;
	}

	public void setOrdenesDeCotizacion(
			Set<OrdenDeCotizacionCliente> ordenesDeCotizacion) {
		this.ordenesDeCotizacion = ordenesDeCotizacion;
	}

	public Set<DescuentoCliente> getDescuentos() {
		return descuentos;
	}

	public void setDescuentos(Set<DescuentoCliente> descuentos) {
		this.descuentos = descuentos;
	}
	
	public OrdenDeCotizacionCliente obtenerOrdenDeCotizacion(Integer codigo)
	{
		Iterator<OrdenDeCotizacionCliente> i = ordenesDeCotizacion.iterator();
		while(i.hasNext())
		{
			OrdenDeCotizacionCliente item = i.next();
			if (item.getCodigo().equals(codigo))
				return item;
		}
		return null;
	}
	
	public OrdenDePedidoCliente obtenerOrdenDePedido(Integer codigo)
	{
		Iterator<OrdenDePedidoCliente> i = ordenesDePedidos.iterator();
		if (codigo.equals(Integer.MAX_VALUE)){
			codigo = 0;
			while(i.hasNext())
			{
				OrdenDePedidoCliente item = i.next();
				if (codigo < item.getCodigo())
					codigo = item.getCodigo();
			}
			return obtenerOrdenDePedido(codigo);
		}
		else
		{
			while(i.hasNext())
			{
				OrdenDePedidoCliente item = i.next();
				if (item.getCodigo().equals(codigo))
					return item;
			}
		}
		return null;
	}
	
	public CondicionDePagoCliente obtenerCondicionDePago(Integer codigo)
	{
		Iterator<CondicionDePagoCliente> i = condicionesDePago.iterator();
		while(i.hasNext())
		{
			CondicionDePagoCliente item = i.next();
			if (item.getCodigo().equals(codigo))
				return item;
		}
		return null;
	}

	public void agregarCondicionDePago(CondicionDePago condicionDePago, Float interes)
	{
		if (!existeCondicionDePago(condicionDePago))
		{
			CondicionDePagoCliente item = new CondicionDePagoCliente();
			item.setCondicionDePago(condicionDePago);
			item.setInteres(interes);
			condicionesDePago.add(item);
		}
	}
	
	public boolean existeCondicionDePago(CondicionDePago condicionDePago)
	{
		Iterator<CondicionDePagoCliente> i = condicionesDePago.iterator();
		while(i.hasNext())
		{
			CondicionDePagoCliente item = i.next();
			if (item.getCondicionDePago().equals(condicionDePago))
				return true;
		}
		return false;	
	}
	public void eliminarCondicionDePago(Integer codigo)
	{
		CondicionDePagoCliente item = obtenerCondicionDePago(codigo);
		if (item!=null)
		{
			condicionesDePago.remove(item);	
		}
	}
	
	public DescuentoCliente obtenerDescuento(Integer codigoDescuento)
	{
		Iterator<DescuentoCliente> i = descuentos.iterator();
		while(i.hasNext())
		{
			DescuentoCliente item = i.next();
			if (item.getCodigo().equals(codigoDescuento))
				return item;
		}
		return null;
	}
	
	public void agregarDescuento(String nombre, Float descuento, Marca marca)
	{
		DescuentoClienteMarca item = new DescuentoClienteMarca();
		item.setNombre(nombre);
		item.setDescuento(descuento);
		item.setMarca(marca);
		descuentos.add(item);
	}
	
	public void agregarDescuento(String nombre, Float descuento, Nacionalidad nacionalidad)
	{
		DescuentoClienteNacionalidad item = new DescuentoClienteNacionalidad();
		item.setNombre(nombre);
		item.setDescuento(descuento);
		item.setNacionalidad(nacionalidad);
		descuentos.add(item);
	}
	
	public void agregarDescuento(String nombre, Float descuento, Producto producto)
	{
		DescuentoClienteProducto item = new DescuentoClienteProducto();
		item.setNombre(nombre);
		item.setDescuento(descuento);
		item.setProducto(producto);
		descuentos.add(item);
	}	
	
	public void agregarDescuento(String nombre, Float descuento, SKF skf)
	{
		DescuentoClienteSKF item = new DescuentoClienteSKF();
		item.setNombre(nombre);
		item.setDescuento(descuento);
		item.setSkf(skf);
		descuentos.add(item);
	}	
	
	public void eliminarDescuento(Integer codigoDescuento)
	{
		DescuentoCliente item = obtenerDescuento(codigoDescuento);
		if (item!=null)
		{
			descuentos.remove(item);	
		}
	}
	
	public boolean equals(Object obj)
	{
		if (obj != null && this.getClass().isInstance(obj)){
			Cliente tmp = (Cliente)obj;
			return codigo.equals(tmp.getCodigo());
		}
		return false;
	}
}
